﻿using System;
using Algoritmia.DataStructures.Lists;
using System.Numerics;
using Algoritmia.Utils;

namespace Algoritmia.Problems.Fourier
{
    public class DiscreteFourierTransform : IDiscreteFourierTransform
    {
        private readonly int _n;
        private readonly Complex _wn;
        private readonly Func<IList<Complex>> _createList;

        public DiscreteFourierTransform(int N,Func<IList<Complex>> createList = null)
        {
            _n = N;
            _wn = Complex.Exp(new Complex(0, 2 * Math.PI) / N);
            _createList = createList ?? (() => AlgoritmiaFactory.Lists<Complex>.Default);
        }

        #region Implementation of IDiscreteFourierTransform

        public IList<Complex> Transform(IList<Complex> complexs)
        {
            var result = _createList();
            for(int k = 0; k < _n; k++)
            {
                Complex complex = 0;
                for(int j = 0; j < _n; j++)
                {
                    complex += complexs[j] * Complex.Pow(_wn,-j*k);
                }
                result.Add(complex);
            }
            return result;
        }

        #endregion
    }
}
